package main

import (
	"fmt"
	"unsafe"
)

type Book struct {
	Title  string
	Author string
	Page   uint
	Tag    []string
}

const (
	//求出Tag相对于Book结构体的地址偏移
	N = unsafe.Offsetof(Book{}.Tag)
	//求出Book.Tag中值的占位的字节长度
	M = unsafe.Sizeof(Book{}.Tag[0])
)

func main() {
	b := Book{Tag: []string{"abc", "def", "hjk"}}
	/***
	unsafe.Pointer(&b)：unsafe.Pointer将&b指针转换成非类型安全指针
	uintptr(unsafe.Pointer(&b))：uintptr将非类型安全指着转换成可用于计算的值
	uintptr(unsafe.Pointer(&b))+N：计算出b.Tag的内存地址
	*[]string和*string：用于类型断言
	***/
	fmt.Printf("Tag切片的内存地址是:%p\n", (*[]string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b))+N)))
	fmt.Printf("Tag切片的值是:%q\n", *((*[]string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b)) + N))))
	fmt.Printf("Tag[0]的内存地址是:%p", unsafe.Pointer(&b.Tag[0]))
	fmt.Printf("---存储的值:%v\n", *(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b.Tag[0])))))
	fmt.Printf("Tag[1]的内存地址是:%p", unsafe.Pointer(&b.Tag[1]))
	fmt.Printf("---存储的值:%v\n", *(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b.Tag[1])))))
	fmt.Printf("Tag[2]的内存地址是:%p", unsafe.Pointer(&b.Tag[2]))
	fmt.Printf("---存储的值:%v\n", *(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b.Tag[2])))))
}
